/**
 * Created by henian.xu on 2017/7/5 0005.
 * jquery插件开发模板 plugName
 */

define(
    [
        'jquery'
    ],
    function ($) {
        var
            plugName = 'xMenu',
            plugVersion = '0.1.0',
            $doc = $(document);

        /**
         * 定义插件类构造函数
         * @param el
         * @param options
         */
        $[plugName] = function (el, options) {
            this.version = plugVersion;
            this.$target = $(el);
            this.$target.data('x-' + plugName, this);// 缓存实例对象

            var
                _super = this,
                cfg = $.extend(true, {}, $[plugName].defaults, options),
                isFloat = _super.$target.is('.x-menu-float,.x-menu-nav'),
                methods = {};

            // 私有方法
            methods = {
                /**
                 * 插件初始化
                 */
                init: function () {
                    methods.initElement();
                    methods.initEvent();
                    methods.lazyHandle();
                },
                /**
                 * 惰性实例化 处理方法
                 */
                lazyHandle: function () {
                    if (cfg.isLazy === null)return;
                    var event = cfg.isLazy;
                    $(event.target).trigger(event);
                },
                /**
                 * 初始化元素
                 */
                initElement: function () {
                    cfg.trigger = cfg.trigger || _super.$target.data('trigger') || 'hover';
                    // 缩进子菜单
                    var $label = _super.$target.find('.x-menu-item-label');
                    if (!isFloat) {
                        $label.each(function () {
                            var $this = $(this),
                                indent = $this.parentsUntil('.x-menu', '.x-menu-submenu').length;
                            $this.css({paddingLeft: indent * 16 + 16 + 'px'});
                        })
                    }
                },
                /**
                 * 初始化事件绑定
                 */
                initEvent: function () {
                    _super.$target.on('mouseenter', '.x-menu-item', function (e) {
                        return methods.onItemHover.call(this, e)
                    });
                    _super.$target.on('mouseleave', '.x-menu-item', function (e) {
                        return methods.onItemLeave.call(this, e)
                    });
                    _super.$target.on('click', '.x-menu-item-label', function (e) {
                        return methods.onItemLabelClick.call(this, e);
                    });
                },
                /**
                 * 鼠标移入 item 时事件
                 * @param event
                 * @param _that
                 */
                onItemHover: function (event) {
                    // _that.isFloat && $(this).children('.x-menu-item-label').trigger('click');
                    if (cfg.trigger !== 'hover')return;
                    var $this = $(this),
                        $thisClosest = $this.closest('.x-menu-item'),
                        isSubmenu = $thisClosest.children('.x-menu-submenu').length > 0;
                    isSubmenu && $thisClosest.addClass('extend');
                },
                /**
                 * 鼠标移出 item 时事件
                 * @param event
                 * @param _that
                 */
                onItemLeave: function (event) {
                    if (cfg.trigger !== 'hover')return;
                    var $this = $(this),
                        $thisClosest = $this.closest('.x-menu-item'),
                        isSubmenu = $thisClosest.children('.x-menu-submenu').length > 0;
                    isSubmenu && $thisClosest.removeClass('extend');
                },
                /**
                 * itemLabel 点击事件
                 * @param event
                 * @param _that
                 */
                onItemLabelClick: function (event) {
                    if (cfg.trigger !== 'click') {
                        isFloat && _super.$target.find('.x-menu-item.extend').removeClass('extend');
                        return;
                    }
                    var $this = $(this),
                        $thisClosest = $this.closest('.x-menu-item'),
                        isExtend = $thisClosest.hasClass('extend'),
                        isSubmenu = $thisClosest.children('.x-menu-submenu').length > 0;
                    // $submenu = $this.parentsUntil('.x-menu', '.x-menu-submenu');
                    if (isSubmenu) {
                        isExtend ? $thisClosest.removeClass('extend') : $thisClosest.addClass('extend');
                    } else {
                        if (isFloat) {
                            _super.$target.find('.x-menu-item.extend').removeClass('extend');
                        } else {
                            _super.$target.find('.x-menu-item.active').removeClass('active');
                            $thisClosest.addClass('active');
                        }
                    }

                    isFloat && methods.clickOutSide(function (e) {
                        _super.$target.find('.x-menu-item.extend').removeClass('extend');
                    });
                },
                /**
                 * 是否是本例子节点
                 * @param $el
                 * @returns {boolean}
                 */
                ischildren: function ($el) {
                    return $el.closest('.' + _super.$target.attr('class').split(' ').join('.')).get(0) === _super.$target.get(0);
                },
                /**
                 * 在元素外面点击
                 * @param callBack
                 */
                clickOutSide: (function () {
                    var isRun = false, _callBack = null;
                    var fn = function (e) {
                        if (methods.ischildren($(e.target)))return;
                        $doc.off('click', fn);
                        _callBack(e);
                        isRun = false;
                    };
                    return function (callBack) {
                        if (isRun)return;
                        isRun = true;
                        _callBack = callBack;
                        $doc.on('click', fn);
                    }
                })()
            };
            methods.init();
        };

        // 公开方法
        var plugPro = $[plugName].prototype; // 简化原形

        /**
         * 注册插件
         * @param options
         * @returns {*}
         */
        $.fn[plugName] = function (options) {
            options = options || {};
            if ($.type(options) === 'object') {
                return this.each(function () {
                    var $plug = $(this).data('x-' + plugName);
                    if ($plug === undefined) {
                        new $[plugName](this, options);
                    } else {
                        // 实例对象已经存在
                    }
                });
            } else {
                // 其它参数类型
            }
        };

        // 默认设置
        $[plugName].defaults = {
            isLazy: null, // 一个事件对象
            trigger: null // 触发方式 click/hover 默认: hover
        };

        // 惰性实例化插件
        $doc.on('click mouseenter', '.x-menu', function (e) {
            var
                $this = $(this);
            if ($this.data('x-' + plugName) !== undefined)return;
            new $[plugName](this, {isLazy: e});
        });

        return $[plugName];
    }
);
